/*
 * EmployeeWindow.java
 * 
 * Copyright (c) 2008, Marshall Scorcio, Ralph Holzmann, 
 *                     Stewart Sweet, Tyler Hoersch, Jeffery Van Handel
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the University of Wisconsin Oshkosh nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */
 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.*;
import javax.swing.GroupLayout.*;
import javax.swing.event.*;
import java.util.*;
import java.text.*;

public class EmployeeWindow extends JFrame implements ActionListener, ListSelectionListener
{   
    private SimpleDateFormat dateFormat;
    
    private EventListenerList listenerList;

    private JSplitPane mainSplitPane;

    private JPanel selectionPanel;
    private JList employeeList;
    private DefaultListModel employeeListModel;
    private JScrollPane employeeScrollPane;
    private JButton deleteButton;
    private JButton addButton;
    private Box addDeleteBox;
    
    private JPanel propertiesPanel;
    private JTabbedPane propertiesTabbedPane;
    private Box cancelApplyBox;
    private JButton cancelButton;
    private JButton applyButton;
    
    private JPanel informationPanel;
    private JTextField nameTextField;
    private JTextField idTextField;
    private JTextField positionTextField;
    private JSlider experienceLevelSlider;
    private JTextField emailTextField;
    private JLabel nameLabel;
    private JLabel idLabel;
    private JLabel positionLabel;
    private JLabel experienceLevelLabel;
    private JLabel emailLabel;

    private JPanel availabilityPanel;
   
    private SpinnerDateModel mondayStartTimeModel;
    private SpinnerDateModel mondayEndTimeModel;
	private JCheckBox mondayAvailableAllDayCheckBox;
	private JCheckBox mondayNotAvailableCheckBox;
    private JSpinner mondayStartTimeSpinner;
    private JSpinner mondayEndTimeSpinner;
    private JSpinner.DateEditor mondayStartTimeEditor;
    private JSpinner.DateEditor mondayEndTimeEditor;
    private JLabel mondayLabel;
    private JLabel mondayFromLabel;
    private JLabel mondayEndLabel;

    private SpinnerDateModel tuesdayStartTimeModel;
    private SpinnerDateModel tuesdayEndTimeModel;
    private JSpinner tuesdayStartTimeSpinner;
    private JSpinner tuesdayEndTimeSpinner;
    private JSpinner.DateEditor tuesdayStartTimeEditor;
    private JSpinner.DateEditor tuesdayEndTimeEditor;
    private JLabel tuesdayLabel;
    private JLabel tuesdayFromLabel;
    private JLabel tuesdayEndLabel;
	private JCheckBox tuesdayAvailableAllDayCheckBox;
	private JCheckBox tuesdayNotAvailableCheckBox;

    private SpinnerDateModel wednesdayStartTimeModel;
    private SpinnerDateModel wednesdayEndTimeModel;
    private JSpinner wednesdayStartTimeSpinner;
    private JSpinner wednesdayEndTimeSpinner;
    private JSpinner.DateEditor wednesdayStartTimeEditor;
    private JSpinner.DateEditor wednesdayEndTimeEditor;
    private JLabel wednesdayLabel;
    private JLabel wednesdayFromLabel;
    private JLabel wednesdayEndLabel;
	private JCheckBox wednesdayAvailableAllDayCheckBox;
	private JCheckBox wednesdayNotAvailableCheckBox;

    private SpinnerDateModel thursdayStartTimeModel;
    private SpinnerDateModel thursdayEndTimeModel;
    private JSpinner thursdayStartTimeSpinner;
    private JSpinner thursdayEndTimeSpinner;
    private JSpinner.DateEditor thursdayStartTimeEditor;
    private JSpinner.DateEditor thursdayEndTimeEditor;
    private JLabel thursdayLabel;
    private JLabel thursdayFromLabel;
    private JLabel thursdayEndLabel;
	private JCheckBox thursdayAvailableAllDayCheckBox;
	private JCheckBox thursdayNotAvailableCheckBox;

    private SpinnerDateModel fridayStartTimeModel;
    private SpinnerDateModel fridayEndTimeModel;
    private JSpinner fridayStartTimeSpinner;
    private JSpinner fridayEndTimeSpinner;
    private JSpinner.DateEditor fridayStartTimeEditor;
    private JSpinner.DateEditor fridayEndTimeEditor;
    private JLabel fridayLabel;
    private JLabel fridayFromLabel;
    private JLabel fridayEndLabel;
	private JCheckBox fridayAvailableAllDayCheckBox;
	private JCheckBox fridayNotAvailableCheckBox;

    private SpinnerDateModel saturdayStartTimeModel;
    private SpinnerDateModel saturdayEndTimeModel;
    private JSpinner saturdayStartTimeSpinner;
    private JLabel saturdayFromLabel;
    private JSpinner saturdayEndTimeSpinner;
    private JSpinner.DateEditor saturdayStartTimeEditor;
    private JSpinner.DateEditor saturdayEndTimeEditor;
    private JLabel saturdayLabel;
    private JLabel saturdayEndLabel;
	private JCheckBox saturdayAvailableAllDayCheckBox;
	private JCheckBox saturdayNotAvailableCheckBox;

    private SpinnerDateModel sundayStartTimeModel;
    private SpinnerDateModel sundayEndTimeModel;
    private JSpinner sundayStartTimeSpinner;
    private JSpinner sundayEndTimeSpinner;
    private JSpinner.DateEditor sundayStartTimeEditor;
    private JSpinner.DateEditor sundayEndTimeEditor;
    private JLabel sundayLabel;
    private JLabel sundayFromLabel;
    private JLabel sundayEndLabel;
	private JCheckBox sundayAvailableAllDayCheckBox;
	private JCheckBox sundayNotAvailableCheckBox;

    private JScrollPane timeOffScrollPane;
    private DefaultTableModel timeOffModel;
    private DefaultListSelectionModel timeOffSelectionModel;
    private JTable timeOffTable;
    private JButton addRequestedDayOffButton;
    private JButton removeRequestedDayOffButton;
    private JPanel timeOffPanel;
    private JPanel timeOffButtonsPanel;
    
    public EmployeeWindow()
    {
        super("Manage Employees");
        setSize(925, 740);
        
        initComponents();
        rootPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        
        listenerList = new EventListenerList();
        dateFormat = new SimpleDateFormat("hh:mm a");
    }
    
    private void initComponents() 
    {
        String timeOffColumnNames[] = {"Date", "Time", "Reason"};
     
        mainSplitPane = new JSplitPane();
        selectionPanel = new JPanel();
        
        employeeListModel = new DefaultListModel();
        employeeList = new JList(employeeListModel);
        employeeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        
        employeeScrollPane = new JScrollPane(employeeList);
        deleteButton = new JButton("Delete");
        addButton = new JButton("Add");
        addDeleteBox = Box.createHorizontalBox();
        
        propertiesPanel = new JPanel();
        propertiesTabbedPane = new JTabbedPane();
        cancelApplyBox = Box.createHorizontalBox();
        cancelButton = new JButton("Cancel");
        applyButton = new JButton("Apply");
        
        informationPanel = new JPanel();        
        nameTextField = new JTextField(20);
        idTextField = new JTextField(20);
        positionTextField = new JTextField(20);
        experienceLevelSlider = new JSlider(1, 10, 1);
        emailTextField = new JTextField(20);
        nameLabel = new JLabel("Name:");
        idLabel = new JLabel("ID:");
        positionLabel = new JLabel("Position:");
        experienceLevelLabel = new JLabel("Experience Level:");
        emailLabel = new JLabel("Email:");

        availabilityPanel = new JPanel();
            
        sundayLabel = new JLabel("Sunday");
        sundayFromLabel = new JLabel("From:");
        sundayEndLabel = new JLabel("Until:");
		  sundayStartTimeModel = new SpinnerDateModel(new Date(), null, null, Calendar.HOUR_OF_DAY);
		  sundayEndTimeModel = new SpinnerDateModel(new Date(), null, null, Calendar.HOUR_OF_DAY);
		  sundayStartTimeSpinner = new JSpinner(sundayStartTimeModel);
		  sundayEndTimeSpinner = new JSpinner(sundayEndTimeModel);
		  sundayStartTimeEditor = new JSpinner.DateEditor(sundayStartTimeSpinner, "hh:mm a");
		  sundayEndTimeEditor = new JSpinner.DateEditor(sundayEndTimeSpinner, "hh:mm a");
        sundayStartTimeSpinner.setEditor(sundayStartTimeEditor);
        sundayEndTimeSpinner.setEditor(sundayEndTimeEditor);
        sundayAvailableAllDayCheckBox = new JCheckBox("Available All Day");
        sundayNotAvailableCheckBox = new JCheckBox("Not Available");
        sundayAvailableAllDayCheckBox.addActionListener(this);
        sundayNotAvailableCheckBox.addActionListener(this);
        
        mondayLabel = new JLabel("Monday");
        mondayFromLabel = new JLabel("From:");
        mondayEndLabel = new JLabel("Until:");
		  mondayStartTimeModel = new SpinnerDateModel(new Date(), null, null, Calendar.HOUR_OF_DAY);
		  mondayEndTimeModel = new SpinnerDateModel(new Date(), null, null, Calendar.HOUR_OF_DAY);
		  mondayStartTimeSpinner = new JSpinner(mondayStartTimeModel);
		  mondayEndTimeSpinner = new JSpinner(mondayEndTimeModel);
		  mondayStartTimeEditor = new JSpinner.DateEditor(mondayStartTimeSpinner, "hh:mm a");
		  mondayEndTimeEditor = new JSpinner.DateEditor(mondayEndTimeSpinner, "hh:mm a");
        mondayStartTimeSpinner.setEditor(mondayStartTimeEditor);
        mondayEndTimeSpinner.setEditor(mondayEndTimeEditor);
        mondayAvailableAllDayCheckBox = new JCheckBox("Available All Day");
        mondayNotAvailableCheckBox = new JCheckBox("Not Available");
        mondayAvailableAllDayCheckBox.addActionListener(this);
        mondayNotAvailableCheckBox.addActionListener(this);

        tuesdayLabel = new JLabel("Tuesday");
        tuesdayFromLabel = new JLabel("From:");
        tuesdayEndLabel = new JLabel("Until:");
		  tuesdayStartTimeModel = new SpinnerDateModel(new Date(), null, null, Calendar.HOUR_OF_DAY);
		  tuesdayEndTimeModel = new SpinnerDateModel(new Date(), null, null, Calendar.HOUR_OF_DAY);
		  tuesdayStartTimeSpinner = new JSpinner(tuesdayStartTimeModel);
		  tuesdayEndTimeSpinner = new JSpinner(tuesdayEndTimeModel);
		  tuesdayStartTimeEditor = new JSpinner.DateEditor(tuesdayStartTimeSpinner, "hh:mm a");
		  tuesdayEndTimeEditor = new JSpinner.DateEditor(tuesdayEndTimeSpinner, "hh:mm a");
        tuesdayStartTimeSpinner.setEditor(tuesdayStartTimeEditor);
        tuesdayEndTimeSpinner.setEditor(tuesdayEndTimeEditor);
        tuesdayAvailableAllDayCheckBox = new JCheckBox("Available All Day");
        tuesdayNotAvailableCheckBox = new JCheckBox("Not Available");
        tuesdayAvailableAllDayCheckBox.addActionListener(this);
        tuesdayNotAvailableCheckBox.addActionListener(this);

        wednesdayLabel = new JLabel("Wednesday");
        wednesdayFromLabel = new JLabel("From:");
        wednesdayEndLabel = new JLabel("Until:");
		  wednesdayStartTimeModel = new SpinnerDateModel(new Date(), null, null, Calendar.HOUR_OF_DAY);
		  wednesdayEndTimeModel = new SpinnerDateModel(new Date(), null, null, Calendar.HOUR_OF_DAY);
		  wednesdayStartTimeSpinner = new JSpinner(wednesdayStartTimeModel);
		  wednesdayEndTimeSpinner = new JSpinner(wednesdayEndTimeModel);
		  wednesdayStartTimeEditor = new JSpinner.DateEditor(wednesdayStartTimeSpinner, "hh:mm a");
		  wednesdayEndTimeEditor = new JSpinner.DateEditor(wednesdayEndTimeSpinner, "hh:mm a");
        wednesdayStartTimeSpinner.setEditor(wednesdayStartTimeEditor);
        wednesdayEndTimeSpinner.setEditor(wednesdayEndTimeEditor);
        wednesdayAvailableAllDayCheckBox = new JCheckBox("Available All Day");
        wednesdayNotAvailableCheckBox = new JCheckBox("Not Available");
        wednesdayAvailableAllDayCheckBox.addActionListener(this);
        wednesdayNotAvailableCheckBox.addActionListener(this);

        thursdayLabel = new JLabel("Thursday");
        thursdayFromLabel = new JLabel("From:");
        thursdayEndLabel = new JLabel("Until:");
		  thursdayStartTimeModel = new SpinnerDateModel(new Date(), null, null, Calendar.HOUR_OF_DAY);
		  thursdayEndTimeModel = new SpinnerDateModel(new Date(), null, null, Calendar.HOUR_OF_DAY);
		  thursdayStartTimeSpinner = new JSpinner(thursdayStartTimeModel);
		  thursdayEndTimeSpinner = new JSpinner(thursdayEndTimeModel);
		  thursdayStartTimeEditor = new JSpinner.DateEditor(thursdayStartTimeSpinner, "hh:mm a");
		  thursdayEndTimeEditor = new JSpinner.DateEditor(thursdayEndTimeSpinner, "hh:mm a");
        thursdayStartTimeSpinner.setEditor(thursdayStartTimeEditor);
        thursdayEndTimeSpinner.setEditor(thursdayEndTimeEditor);
        thursdayAvailableAllDayCheckBox = new JCheckBox("Available All Day");
        thursdayNotAvailableCheckBox = new JCheckBox("Not Available");
        thursdayAvailableAllDayCheckBox.addActionListener(this);
        thursdayNotAvailableCheckBox.addActionListener(this);
        
        fridayLabel = new JLabel("Friday");
        fridayFromLabel = new JLabel("From:");
        fridayEndLabel = new JLabel("Until:");
		  fridayStartTimeModel = new SpinnerDateModel(new Date(), null, null, Calendar.HOUR_OF_DAY);
		  fridayEndTimeModel = new SpinnerDateModel(new Date(), null, null, Calendar.HOUR_OF_DAY);
		  fridayStartTimeSpinner = new JSpinner(fridayStartTimeModel);
		  fridayEndTimeSpinner = new JSpinner(fridayEndTimeModel);
		  fridayStartTimeEditor = new JSpinner.DateEditor(fridayStartTimeSpinner, "hh:mm a");
		  fridayEndTimeEditor = new JSpinner.DateEditor(fridayEndTimeSpinner, "hh:mm a");
        fridayStartTimeSpinner.setEditor(fridayStartTimeEditor);
        fridayEndTimeSpinner.setEditor(fridayEndTimeEditor);
        fridayAvailableAllDayCheckBox = new JCheckBox("Available All Day");
        fridayNotAvailableCheckBox = new JCheckBox("Not Available");
        fridayAvailableAllDayCheckBox.addActionListener(this);
        fridayNotAvailableCheckBox.addActionListener(this);
        
        saturdayLabel = new JLabel("Saturday");
        saturdayFromLabel = new JLabel("From:");
        saturdayEndLabel = new JLabel("Until:");
		  saturdayStartTimeModel = new SpinnerDateModel(new Date(), null, null, Calendar.HOUR_OF_DAY);
		  saturdayEndTimeModel = new SpinnerDateModel(new Date(), null, null, Calendar.HOUR_OF_DAY);
		  saturdayStartTimeSpinner = new JSpinner(saturdayStartTimeModel);
		  saturdayEndTimeSpinner = new JSpinner(saturdayEndTimeModel);
		  saturdayStartTimeEditor = new JSpinner.DateEditor(saturdayStartTimeSpinner, "hh:mm a");
		  saturdayEndTimeEditor = new JSpinner.DateEditor(saturdayEndTimeSpinner, "hh:mm a");
        saturdayStartTimeSpinner.setEditor(saturdayStartTimeEditor);
        saturdayEndTimeSpinner.setEditor(saturdayEndTimeEditor);
        saturdayAvailableAllDayCheckBox = new JCheckBox("Available All Day");
        saturdayNotAvailableCheckBox = new JCheckBox("Not Available");
        saturdayAvailableAllDayCheckBox.addActionListener(this);
        saturdayNotAvailableCheckBox.addActionListener(this);

        GroupLayout availabilityLayout = new GroupLayout(availabilityPanel);
        availabilityLayout.setAutoCreateGaps(true);
        availabilityLayout.setAutoCreateContainerGaps(true);

        SequentialGroup horizontalAvailabilityGroup = availabilityLayout.createSequentialGroup();
        
        horizontalAvailabilityGroup.addGroup(availabilityLayout.createParallelGroup()
            .addComponent(sundayLabel)
            .addComponent(mondayLabel)
            .addComponent(tuesdayLabel)
            .addComponent(wednesdayLabel)
            .addComponent(thursdayLabel)
            .addComponent(fridayLabel)
            .addComponent(saturdayLabel));

        horizontalAvailabilityGroup.addGroup(availabilityLayout.createParallelGroup()
            .addComponent(sundayFromLabel)
            .addComponent(mondayFromLabel)
            .addComponent(tuesdayFromLabel)
            .addComponent(wednesdayFromLabel)
            .addComponent(thursdayFromLabel)
            .addComponent(fridayFromLabel)
            .addComponent(saturdayFromLabel));

        horizontalAvailabilityGroup.addGroup(availabilityLayout.createParallelGroup()
            .addComponent(sundayStartTimeSpinner)
            .addComponent(mondayStartTimeSpinner)
            .addComponent(tuesdayStartTimeSpinner)
            .addComponent(wednesdayStartTimeSpinner)
            .addComponent(thursdayStartTimeSpinner)
            .addComponent(fridayStartTimeSpinner)
            .addComponent(saturdayStartTimeSpinner));

        horizontalAvailabilityGroup.addGroup(availabilityLayout.createParallelGroup()
            .addComponent(sundayEndLabel)
            .addComponent(mondayEndLabel)
            .addComponent(tuesdayEndLabel)
            .addComponent(wednesdayEndLabel)
            .addComponent(thursdayEndLabel)
            .addComponent(fridayEndLabel)
            .addComponent(saturdayEndLabel));

        horizontalAvailabilityGroup.addGroup(availabilityLayout.createParallelGroup()
            .addComponent(mondayEndTimeSpinner)
            .addComponent(tuesdayEndTimeSpinner)
            .addComponent(wednesdayEndTimeSpinner)
            .addComponent(thursdayEndTimeSpinner)
            .addComponent(fridayEndTimeSpinner)
            .addComponent(saturdayEndTimeSpinner)
            .addComponent(sundayEndTimeSpinner));
            
        horizontalAvailabilityGroup.addGroup(availabilityLayout.createParallelGroup()
            .addComponent(sundayAvailableAllDayCheckBox)
            .addComponent(mondayAvailableAllDayCheckBox)
            .addComponent(tuesdayAvailableAllDayCheckBox)
            .addComponent(wednesdayAvailableAllDayCheckBox)
            .addComponent(thursdayAvailableAllDayCheckBox)
            .addComponent(fridayAvailableAllDayCheckBox)
            .addComponent(saturdayAvailableAllDayCheckBox));
            
        horizontalAvailabilityGroup.addGroup(availabilityLayout.createParallelGroup()
            .addComponent(sundayNotAvailableCheckBox)
            .addComponent(mondayNotAvailableCheckBox)
            .addComponent(tuesdayNotAvailableCheckBox)
            .addComponent(wednesdayNotAvailableCheckBox)
            .addComponent(thursdayNotAvailableCheckBox)
            .addComponent(fridayNotAvailableCheckBox)
            .addComponent(saturdayNotAvailableCheckBox));
                   
        SequentialGroup verticalAvailabilityGroup = availabilityLayout.createSequentialGroup();
 
 		  verticalAvailabilityGroup.addGroup(availabilityLayout.createParallelGroup(Alignment.BASELINE)
            .addComponent(sundayLabel)
            .addComponent(sundayFromLabel)
            .addComponent(sundayStartTimeSpinner)
            .addComponent(sundayEndLabel)
            .addComponent(sundayEndTimeSpinner)
            .addComponent(sundayAvailableAllDayCheckBox)
            .addComponent(sundayNotAvailableCheckBox));
        
		  verticalAvailabilityGroup.addGroup(availabilityLayout.createParallelGroup(Alignment.BASELINE)
            .addComponent(mondayLabel)
            .addComponent(mondayFromLabel)
            .addComponent(mondayStartTimeSpinner)
            .addComponent(mondayEndLabel)
            .addComponent(mondayEndTimeSpinner)
            .addComponent(mondayAvailableAllDayCheckBox)
            .addComponent(mondayNotAvailableCheckBox));

		  verticalAvailabilityGroup.addGroup(availabilityLayout.createParallelGroup(Alignment.BASELINE)
            .addComponent(tuesdayLabel)
            .addComponent(tuesdayFromLabel)
            .addComponent(tuesdayStartTimeSpinner)
            .addComponent(tuesdayEndLabel)
            .addComponent(tuesdayEndTimeSpinner)
            .addComponent(tuesdayAvailableAllDayCheckBox)
            .addComponent(tuesdayNotAvailableCheckBox));

		  verticalAvailabilityGroup.addGroup(availabilityLayout.createParallelGroup(Alignment.BASELINE)
            .addComponent(wednesdayLabel)
            .addComponent(wednesdayFromLabel)
            .addComponent(wednesdayStartTimeSpinner)
            .addComponent(wednesdayEndLabel)
            .addComponent(wednesdayEndTimeSpinner)
            .addComponent(wednesdayAvailableAllDayCheckBox)
            .addComponent(wednesdayNotAvailableCheckBox));

		  verticalAvailabilityGroup.addGroup(availabilityLayout.createParallelGroup(Alignment.BASELINE)
            .addComponent(thursdayLabel)
            .addComponent(thursdayFromLabel)
            .addComponent(thursdayStartTimeSpinner)
            .addComponent(thursdayEndLabel)
            .addComponent(thursdayEndTimeSpinner)
            .addComponent(thursdayAvailableAllDayCheckBox)
            .addComponent(thursdayNotAvailableCheckBox));

		  verticalAvailabilityGroup.addGroup(availabilityLayout.createParallelGroup(Alignment.BASELINE)
            .addComponent(fridayLabel)
            .addComponent(fridayFromLabel)
            .addComponent(fridayStartTimeSpinner)
            .addComponent(fridayEndLabel)
            .addComponent(fridayEndTimeSpinner)
            .addComponent(fridayAvailableAllDayCheckBox)
            .addComponent(fridayNotAvailableCheckBox));

		  verticalAvailabilityGroup.addGroup(availabilityLayout.createParallelGroup(Alignment.BASELINE)
            .addComponent(saturdayLabel)
            .addComponent(saturdayFromLabel)
            .addComponent(saturdayStartTimeSpinner)
            .addComponent(saturdayEndLabel)
            .addComponent(saturdayEndTimeSpinner)
            .addComponent(saturdayAvailableAllDayCheckBox)
            .addComponent(saturdayNotAvailableCheckBox));

        availabilityLayout.setHorizontalGroup(horizontalAvailabilityGroup);
        availabilityLayout.setVerticalGroup(verticalAvailabilityGroup);
        
        availabilityPanel.setLayout(availabilityLayout);
        
        timeOffModel = new DefaultTableModel(timeOffColumnNames, 0)
        {
            @Override
            public boolean isCellEditable(int row, int column)
            {
                return false;
            }
        };
        timeOffSelectionModel = new DefaultListSelectionModel();
        timeOffTable = new JTable(timeOffModel);
        timeOffScrollPane = new JScrollPane(timeOffTable);
        addRequestedDayOffButton = new JButton("Add Request");
        removeRequestedDayOffButton = new JButton("Remove Request");
        
        timeOffPanel = new JPanel(new BorderLayout());
        timeOffButtonsPanel = new JPanel();
        
        timeOffSelectionModel.addListSelectionListener(this);
        timeOffTable.setSelectionModel(timeOffSelectionModel);
        timeOffPanel.add(timeOffScrollPane, BorderLayout.CENTER);        
        
        removeRequestedDayOffButton.setEnabled(false);
        
        timeOffButtonsPanel.add(addRequestedDayOffButton);
        timeOffButtonsPanel.add(removeRequestedDayOffButton);
        
        timeOffPanel.add(timeOffButtonsPanel, BorderLayout.SOUTH);
        
        cancelButton.addActionListener(this);
        applyButton.addActionListener(this);
        addRequestedDayOffButton.addActionListener(this);
        removeRequestedDayOffButton.addActionListener(this);
        
        cancelApplyBox.add(Box.createHorizontalGlue());
        cancelApplyBox.add(cancelButton);
        cancelApplyBox.add(applyButton);
                
        addButton.addActionListener(this);
        deleteButton.addActionListener(this);
        
        addDeleteBox.add(Box.createHorizontalGlue());
        addDeleteBox.add(deleteButton);
        addDeleteBox.add(addButton);        
        
        employeeList.addListSelectionListener(this);        
        selectionPanel.setLayout(new BorderLayout());
        selectionPanel.add(employeeScrollPane, BorderLayout.CENTER);
        selectionPanel.add(addDeleteBox, BorderLayout.SOUTH);
       
        GroupLayout informationLayout = new GroupLayout(informationPanel);
        informationLayout.setAutoCreateGaps(true);
        informationLayout.setAutoCreateContainerGaps(true);
		
        experienceLevelSlider.setSnapToTicks(true);
        experienceLevelSlider.setMajorTickSpacing(1);
        experienceLevelSlider.setPaintLabels(true);
        experienceLevelSlider.setPaintTicks(true);
        
        SequentialGroup horizontalGroup = informationLayout.createSequentialGroup();
        
        horizontalGroup.addGroup(informationLayout.createParallelGroup()
            .addComponent(nameLabel)
            .addComponent(idLabel)
            .addComponent(positionLabel)
            .addComponent(experienceLevelLabel)
            .addComponent(emailLabel));
            
        horizontalGroup.addGroup(informationLayout.createParallelGroup()
            .addComponent(nameTextField)
            .addComponent(idTextField)
            .addComponent(positionTextField)
            .addComponent(experienceLevelSlider)
            .addComponent(emailTextField));

        SequentialGroup verticalGroup = informationLayout.createSequentialGroup();
        
        verticalGroup.addGroup(informationLayout.createParallelGroup(Alignment.BASELINE)
            .addComponent(nameLabel)
            .addComponent(nameTextField));
            
        verticalGroup.addGroup(informationLayout.createParallelGroup(Alignment.BASELINE)
            .addComponent(idLabel)
            .addComponent(idTextField));

        verticalGroup.addGroup(informationLayout.createParallelGroup(Alignment.BASELINE)
            .addComponent(emailLabel)
            .addComponent(emailTextField));
            
        verticalGroup.addGroup(informationLayout.createParallelGroup(Alignment.BASELINE)
            .addComponent(positionLabel)
            .addComponent(positionTextField));
            
        verticalGroup.addGroup(informationLayout.createParallelGroup(Alignment.CENTER)
            .addComponent(experienceLevelLabel)
            .addComponent(experienceLevelSlider));
        
        informationLayout.setHorizontalGroup(horizontalGroup);
        informationLayout.setVerticalGroup(verticalGroup);
        
        informationPanel.setLayout(informationLayout);
        
        propertiesTabbedPane.add("Information", informationPanel);
        propertiesTabbedPane.add("Availability", availabilityPanel);
        propertiesTabbedPane.add("Time Off Requests", timeOffPanel);

        propertiesPanel.setLayout(new BorderLayout());
        propertiesPanel.add(propertiesTabbedPane, BorderLayout.CENTER);
        propertiesPanel.add(cancelApplyBox, BorderLayout.SOUTH);
        
        mainSplitPane.setLeftComponent(selectionPanel);
        mainSplitPane.setRightComponent(propertiesPanel);
        mainSplitPane.setDividerLocation(225);
                
        add(mainSplitPane);
        
        disablePropertiesPanelComponents();
        deleteButton.setEnabled(false);
    }
       
    public void addViewEventListener(ViewEventListener listener)
    {
        listenerList.add(ViewEventListener.class, listener);
    }
    
    public void removeViewEventListener(ViewEventListener listener)
    {
        listenerList.remove(ViewEventListener.class, listener);
    }
    
    private void fireViewEvent(Object source, String name)
    {
        ViewEvent event = new ViewEvent(source, name);
    
        ViewEventListener[] listeners = listenerList.getListeners(ViewEventListener.class);

        for (int i = 0; i < listeners.length; i++)
        {
            listeners[i].viewEventOccurred(event);
        }
    }
    
    public void setEmployees(String[] employees)
    {        
        employeeListModel.removeAllElements();
        
        for (int i = 0; i < employees.length; i++)
        {
            employeeListModel.add(i, employees[i]);
        }
        
        employeeList.setModel(employeeListModel);
    }
    
    public void setEmployeeInformation(String name, String ID, String email, String position, int experienceLevel)
    {
        nameTextField.setText(name);
        idTextField.setText(ID);
        emailTextField.setText(email);
        positionTextField.setText(position);
        experienceLevelSlider.setValue(experienceLevel);
        
        enablePropertiesPanelComponents();
    }
    
    public String[] getEmployeeInformation()
    {
        String[] employeeInformation = { nameTextField.getText(), idTextField.getText(), emailTextField.getText(),
                                         positionTextField.getText(), "" + experienceLevelSlider.getValue() };
                                         
        return employeeInformation;
    }
    
    public String getSelectedEmployee()
    {
        return (String) employeeList.getSelectedValue();
    }
    
    public void setSelectedEmployee(int index)
    {
        employeeList.setSelectedIndex(index);
    }
    
    public void addEmployee(String name)
    {
        employeeListModel.addElement(name);
    }
    
    public void removeEmployee(String name)
    {
        employeeListModel.removeElement(name);
    }
    
    public void addRequestedDayOff(String date, String time, String reason)
    {
        String[] requestedDayOff = { date, time, reason };
        
        timeOffModel.addRow(requestedDayOff);
    }
    
    public void removeRequestedDayOff(String[] requestedDayOff)
    {
        for (int i = 0; i < timeOffModel.getRowCount(); i++)
        {
            if (timeOffModel.getValueAt(i, 0).equals(requestedDayOff[0]))
            {
                timeOffModel.removeRow(i);
            }
        }
    }
    
    public void removeAllRequestedDaysOff()
    {
        for(int i = 0;i < timeOffModel.getRowCount();i++)
        {
            timeOffModel.removeRow(i);
        }
    }
    
    private void addRequestedDayOffButtonPressed()
    {  
        if (!employeeList.isSelectionEmpty())
        {
            DateChooser dateChooser = new DateChooser(this, "Select a Day");
            dateChooser.setLocationRelativeTo(this);
            dateChooser.setVisible(true);
 
            if (dateChooser.isDateChosen())
            {
                fireViewEvent(dateChooser, "AddRequestedDayOff");
            }
        }
        else
        {
            JOptionPane.showMessageDialog(this, "You must select an employee first", 
                                          "No employee selected!", JOptionPane.ERROR_MESSAGE);
        }      
    }
    
    private void removeRequestedDayOffButtonPressed()
    {
        if (timeOffTable.getSelectedRow() != -1)
        {
            fireViewEvent(removeRequestedDayOffButton, "RemoveRequestedDayOff");
        }
        else
        {
            JOptionPane.showMessageDialog(this, "You must select a requested day off to remove",
                                          "No request selected", JOptionPane.ERROR_MESSAGE);
        }
    }
        
    private void applyButtonPressed() 
    {
        if(!employeeList.isSelectionEmpty())
        {
            fireViewEvent(applyButton, "Apply");
        }
        else
        {
            JOptionPane.showMessageDialog(this, "No employee selected to apply changes.",
                                          "No Selection", JOptionPane.ERROR_MESSAGE);
        }
    }
    
    public String[] getSelectedRequestedDayOff()
    {
        String[] requestedDayOff;
        
        int selectedRow = timeOffTable.getSelectedRow();
        
        if (selectedRow != -1)
        {
            requestedDayOff = new String[timeOffTable.getColumnCount()];
            for (int i = 0; i < timeOffTable.getColumnCount(); i++)
            {
                requestedDayOff[i] = (String) timeOffTable.getValueAt(selectedRow, i);
            }
        }
        else
        {
            requestedDayOff = null;
        }
            
        return requestedDayOff;
    }
    
    public String[][] getRequestedDaysOff()
    {
        String[][] requestedDaysOff = new String[timeOffTable.getRowCount()][timeOffTable.getColumnCount()];
        
        for (int i = 0; i < timeOffTable.getRowCount(); i++)
        {
            for (int j = 0; j < timeOffTable.getColumnCount(); j++)
            {
                requestedDaysOff[i][j] = (String) timeOffTable.getValueAt(i, j);
            }
        }
        
        return requestedDaysOff;
    }

    public void resetPropertiesPanel()
    {
        nameTextField.setText("");
        idTextField.setText("");
        emailTextField.setText("");
        positionTextField.setText("");
        experienceLevelSlider.setValue(1);
        
        for (int i = 0; i < timeOffModel.getRowCount(); i++)
        {
            timeOffModel.removeRow(i);
        }
                
        propertiesTabbedPane.setSelectedComponent(informationPanel);
    }
    
    public void disablePropertiesPanelComponents()
    {
        nameTextField.setEnabled(false);
        idTextField.setEnabled(false);
        emailTextField.setEnabled(false);
        positionTextField.setEnabled(false);
        experienceLevelSlider.setEnabled(false);
        
        nameLabel.setEnabled(false);
        idLabel.setEnabled(false);
        emailLabel.setEnabled(false);
        positionLabel.setEnabled(false);
        experienceLevelLabel.setEnabled(false);
        
        propertiesTabbedPane.setEnabled(false);
        applyButton.setEnabled(false);
        cancelButton.setEnabled(false);
    }
    
    public void enablePropertiesPanelComponents()
    {
        nameTextField.setEnabled(true);
        idTextField.setEnabled(true);
        emailTextField.setEnabled(true);
        positionTextField.setEnabled(true);
        experienceLevelSlider.setEnabled(true);
        
        nameLabel.setEnabled(true);
        idLabel.setEnabled(true);
        emailLabel.setEnabled(true);
        positionLabel.setEnabled(true);
        experienceLevelLabel.setEnabled(true);
        
        applyButton.setEnabled(true);
        cancelButton.setEnabled(true);
        propertiesTabbedPane.setEnabled(true);
    }

    public String[] getAvailability()
    {
        String[] availability = new String[7];
        
        for (int i = 0; i < availability.length; i++)
        {
            availability[i] = dateFormat.format(((SpinnerDateModel) getAvailabilityStartTimeSpinner(i).getModel()).getDate()) + " - " 
                              + dateFormat.format(((SpinnerDateModel)getAvailabilityEndTimeSpinner(i).getModel()).getDate());
        }
        
        return availability;
    }
       
    public void setAvailability(String[] availability)
    {
        for (int i = 0; i < availability.length; i++)
        {            
            if (availability[i].equals(""))
            {
                getNotAvailableCheckBox(i).setSelected(true);
                toggleNotAvailableCheckBox(i);
            }
            else if (availability[i].equals("12:00 AM - 11:59 PM"))
            {
                getAvailableAllDayCheckBox(i).setSelected(true);
                toggleAvailableAllDayCheckBox(i);
            }
            else
            {
                try
                {
                    ((SpinnerDateModel) getAvailabilityStartTimeSpinner(i).getModel()).setValue(dateFormat.parse(availability[i].substring(0, availability[i].indexOf(" - "))));
                    ((SpinnerDateModel) getAvailabilityEndTimeSpinner(i).getModel()).setValue(dateFormat.parse(availability[i].substring(availability[i].indexOf(" - ") + 3)));
                }
                catch (ParseException exception)
                {
                    System.out.println(exception);
                }
            }
        }
    }
    
    public void resetAvailability()
    {
        for (int i = 0; i < 7; i++)
        {
            getNotAvailableCheckBox(i).setSelected(false);
            getAvailableAllDayCheckBox(i).setSelected(false);
            getAvailabilityStartTimeSpinner(i).setEnabled(true);
            getAvailabilityEndTimeSpinner(i).setEnabled(true);
            ((SpinnerDateModel) getAvailabilityStartTimeSpinner(i).getModel()).setValue(new Date());
            ((SpinnerDateModel) getAvailabilityEndTimeSpinner(i).getModel()).setValue(new Date());
        }
    }
    
    private JSpinner getAvailabilityStartTimeSpinner(int day)
    {
        JSpinner dateSpinner = null;
        
        switch (day)
        {
            case 0:
                dateSpinner = sundayStartTimeSpinner;
                break;
            case 1:
                dateSpinner = mondayStartTimeSpinner;
                break;               
            case 2:
                dateSpinner = tuesdayStartTimeSpinner;
                break;
            case 3:
                dateSpinner = wednesdayStartTimeSpinner;
                break;
            case 4:
                dateSpinner = thursdayStartTimeSpinner;
                break;
            case 5:
                dateSpinner = fridayStartTimeSpinner;
                break;
            case 6:
                dateSpinner = saturdayStartTimeSpinner;
                break;
        }

        return dateSpinner;
    }
    
    private JSpinner getAvailabilityEndTimeSpinner(int day)
    {
        JSpinner dateSpinner = null;
        
        switch (day)
        {
            case 0:
                dateSpinner = sundayEndTimeSpinner;
                break;
            case 1:
                dateSpinner = mondayEndTimeSpinner;
                break;               
            case 2:
                dateSpinner = tuesdayEndTimeSpinner;
                break;
            case 3:
                dateSpinner = wednesdayEndTimeSpinner;
                break;
            case 4:
                dateSpinner = thursdayEndTimeSpinner;
                break;
            case 5:
                dateSpinner = fridayEndTimeSpinner;
                break;
            case 6:
                dateSpinner = saturdayEndTimeSpinner;
                break;
        }

        return dateSpinner;
    }
    
    private JCheckBox getAvailableAllDayCheckBox(int day)
    {
        JCheckBox allDayCheckBox = null;
        
        switch (day)
        {
            case 0:
                allDayCheckBox = sundayAvailableAllDayCheckBox;
                break;
            case 1:
                allDayCheckBox = mondayAvailableAllDayCheckBox;
                break;        
            case 2:
                allDayCheckBox = tuesdayAvailableAllDayCheckBox;
                break;
            case 3:
                allDayCheckBox = wednesdayAvailableAllDayCheckBox;
                break;
            case 4:
                allDayCheckBox = thursdayAvailableAllDayCheckBox;
                break;
            case 5:
                allDayCheckBox = fridayAvailableAllDayCheckBox;
                break;
            case 6:
                allDayCheckBox = saturdayAvailableAllDayCheckBox;
                break;
        }
            
        return allDayCheckBox;
    }
    
    private JCheckBox getNotAvailableCheckBox(int day)
    {    
        JCheckBox notAvailableCheckBox = null;
        
        switch (day)
        {
            case 0:
                notAvailableCheckBox = sundayNotAvailableCheckBox;
                break;
            case 1:
                notAvailableCheckBox = mondayNotAvailableCheckBox;
                break;        
            case 2:
                notAvailableCheckBox = tuesdayNotAvailableCheckBox;
                break;
            case 3:
                notAvailableCheckBox = wednesdayNotAvailableCheckBox;
                break;
            case 4:
                notAvailableCheckBox = thursdayNotAvailableCheckBox;
                break;
            case 5:
                notAvailableCheckBox = fridayNotAvailableCheckBox;
                break;
            case 6:
                notAvailableCheckBox = saturdayNotAvailableCheckBox;
                break;
        }
            
        return notAvailableCheckBox;
    }
    
    public boolean[] isAvailableAllDaySelected()
    {
        boolean[] available = new boolean[7];
        
        for (int i = 0; i < available.length; i++)
        {
            available[i] = getAvailableAllDayCheckBox(i).isSelected();
        }
        
        return available;
    }
    
    public boolean[] isNotAvailableSelected()
    {
        boolean[] notAvailable = new boolean[7];
        
        for (int i = 0; i < notAvailable.length; i++)
        {
            notAvailable[i] = getNotAvailableCheckBox(i).isSelected();
        }
    
        return notAvailable;
    }

    public void unselectCurrentEmployee()
    {
        employeeList.clearSelection();
        disablePropertiesPanelComponents();
        resetPropertiesPanel();
    }
    
    public void toggleAvailableAllDayCheckBox(int day)
    {
        JCheckBox allDayCheckBox = getAvailableAllDayCheckBox(day);
        
        if (allDayCheckBox.isSelected())
        {
            getNotAvailableCheckBox(day).setSelected(false);
            getAvailabilityStartTimeSpinner(day).setEnabled(false);
            getAvailabilityEndTimeSpinner(day).setEnabled(false);
        }
        else
        {
            getNotAvailableCheckBox(day).setSelected(false);
            getAvailabilityStartTimeSpinner(day).setEnabled(true);
            getAvailabilityEndTimeSpinner(day).setEnabled(true);            
        }
    }

    public void toggleNotAvailableCheckBox(int day)
    {
        JCheckBox notAvailableCheckBox = getNotAvailableCheckBox(day);
        
        if (notAvailableCheckBox.isSelected())
        {
            getAvailableAllDayCheckBox(day).setSelected(false);
            getAvailabilityStartTimeSpinner(day).setEnabled(false);
            getAvailabilityEndTimeSpinner(day).setEnabled(false);
        }
        else
        {
            getAvailableAllDayCheckBox(day).setSelected(false);
            getAvailabilityStartTimeSpinner(day).setEnabled(true);
            getAvailabilityEndTimeSpinner(day).setEnabled(true);            
        }      
    }
           
    public void actionPerformed(ActionEvent event)
    {
        if (event.getSource() == addButton)
        {
           fireViewEvent(addButton, "AddEmployee");
        }
        else if (event.getSource() == applyButton)
        {
           applyButtonPressed();
        }
        else if (event.getSource() == deleteButton)
        {
            if (!employeeList.isSelectionEmpty()) 
            {
                fireViewEvent(deleteButton, "DeleteEmployee");
            }
        }
        else if (event.getSource() == cancelButton)
        {
            unselectCurrentEmployee();
        }
        else if (event.getSource() == addRequestedDayOffButton)
        {
            addRequestedDayOffButtonPressed();
        }
        else if (event.getSource() == removeRequestedDayOffButton)
        {
            removeRequestedDayOffButtonPressed();
        }  
        else
        {
            for (int i = 0; i < 7; i++)
            {
                if (event.getSource() == getAvailableAllDayCheckBox(i))
                {
                    toggleAvailableAllDayCheckBox(i);
                }
                else if (event.getSource() == getNotAvailableCheckBox(i))
                {
                    toggleNotAvailableCheckBox(i);
                }
            }
        }
    }
    
    public void valueChanged(ListSelectionEvent event)
    {
        if (event.getSource() == employeeList)
        {
            if (!employeeList.isSelectionEmpty()) 
            {
                fireViewEvent(employeeList, "EmployeeSelectionChanged");
                deleteButton.setEnabled(true);
            }
            else
            {
                deleteButton.setEnabled(false);
            }
        }
        else if (event.getSource() == timeOffSelectionModel)
        {
            if (!timeOffSelectionModel.isSelectionEmpty())
            {
                removeRequestedDayOffButton.setEnabled(true);
            }
            else
            {
                removeRequestedDayOffButton.setEnabled(false);
            }
        }
    }
}
